#include "widget.h"
#include "./ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QStringList list = {};
    ui->comboBox->addItems(list);
    ui->lineEdit->setText("请输入要搜索的字符串...");
    //初始化一个字符串列表的内容
    QStringList m_qStrList ;
    m_qStrList << "*.text" << "*.txt";
    m_qStrListModel = new QStringListModel(this);
    m_qStrListModel->setStringList(m_qStrList);
    ui->listView->setModel(m_qStrListModel);
    ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked
                                  | QAbstractItemView::SelectedClicked);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    QString   search = ui->lineEdit->text();
    // 获取要打开的文件路径
    // QString fileName = QFileDialog::getOpenFileName(
    //                        nullptr,                // 父窗口
    //                        "打开文件",             // 对话框标题
    //                        QDir::homePath(),      // 默认打开的目录
    //                        "文本文件 (*.txt);;所有文件 (*)"  // 文件过滤器
    //                    );
    // if (!fileName.isEmpty()) {
    //     qDebug() << "选择的文件:" << fileName;
    //     std::vector<SearchResult>  results = searchWithLineNumbers(fileName, search.toUtf8());
    //     // 在这里处理文件...
    //     if (results.empty()) {
    //         qDebug() << "未找到匹配内容";
    //     } else {
    //         qDebug() << "找到" << results.size() << "个匹配:";
    //         for (const auto& result : results) {
    //             qDebug() << "行号:" << result.lineNumber
    //                      << "位置:" << result.position
    //                      << "内容:" << result.lineContent;
    //         }
    //     }
    // } else {
    //     qDebug() << "用户取消了选择";
    // }
    QString folderPath = QFileDialog::getExistingDirectory(nullptr, "选择文件夹", QDir::homePath());
    if (!folderPath.isEmpty()) {
        // QStringList filters = {"*.png", "*.jpg", "*.jpeg", "*.bmp"};
        // QStringList filters = {"*.text", "*.txt"};
        // 获取模型中的全部数据作为 QStringList
        QStringList filters = m_qStrListModel->stringList();
        QStringList imageFiles = getFilesWithFilter(folderPath, filters);
        qDebug() << "找到" << imageFiles.size() << "个图片文件:";
        ui->plainTextEdit->clear();
        ui->comboBox->clear();
        ui->plainTextEdit->appendPlainText(QString("一共找到 %1 个文件: ").arg(imageFiles.size()));
        QStringList list;
        for (const QString &file : imageFiles) {
            qDebug() << file;
            std::vector<SearchResult>  results = searchWithLineNumbers(file, search.toUtf8());
            // 在这里处理文件...
            if (results.empty()) {
                qDebug() << "未找到匹配内容";
            } else {
                qDebug() << "找到" << results.size() << "个匹配:";
                QStringList value;
                for (const auto& result : results) {
                    qDebug() << "行号:" << result.lineNumber
                             << "位置:" << result.position
                             << "内容:" << result.lineContent;
                    value.append(QString("行号: %1 位置: %2 内容: %3").arg(result.lineNumber).arg(result.position).arg(result.lineContent));
                }
                resultMap[file] = value;
                ui->plainTextEdit->appendPlainText(file);
                list.append(file);
            }
        }
        ui->plainTextEdit->appendPlainText("");
        for (int i = 0; i < list.size(); ++i) {
            ui->comboBox->addItem(list.at(i));
        }
    }
}
#include <vector>


std::vector<SearchResult> searchWithLineNumbers(const QString &filePath, const QByteArray &searchPattern)
{
    std::vector<SearchResult> results;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开文件:" << filePath;
        return results;
    }
    qint64 fileSize = file.size();
    if (fileSize == 0) {
        return results;
    }
    uchar *memory = file.map(0, fileSize);
    if (!memory) {
        qWarning() << "内存映射失败";
        return results;
    }
    const char *data = reinterpret_cast<const char*>(memory);
    const qint64 patternLength = searchPattern.length();
    int lineNumber = 1;
    qint64 lineStart = 0;
    for (qint64 i = 0; i < fileSize; ++i) {
        // 检查是否匹配搜索模式
        if (i <= fileSize - patternLength &&
            memcmp(data + i, searchPattern.constData(), patternLength) == 0) {
            // 找到行开始和结束
            qint64 lineEnd = i;
            for (; lineEnd < fileSize && data[lineEnd] != '\n'; ++lineEnd) {}
            // 提取整行内容
            QByteArray line(data + lineStart, lineEnd - lineStart);
            results.push_back({
                i,                        // 匹配位置
                lineNumber,                // 行号
                QString::fromUtf8(line)   // 行内容
            });
        }
        // 更新行号信息
        if (data[i] == '\n') {
            lineNumber++;
            lineStart = i + 1;
        }
    }
    file.unmap(memory);
    file.close();
    return results;
}


QStringList getAllFiles(const QString &directoryPath)
{
    QStringList files;
    // 递归遍历所有子目录
    QDirIterator it(directoryPath,
                    QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System,
                    QDirIterator::Subdirectories);
    while (it.hasNext()) {
        files.append(it.next());
    }
    return files;
}

QStringList getFilesWithFilter(const QString &directoryPath, const QStringList &nameFilters)
{
    QStringList files;
    QDirIterator it(directoryPath,
                    nameFilters,
                    QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System,
                    QDirIterator::Subdirectories);
    while (it.hasNext()) {
        files.append(it.next());
    }
    return files;
}

void Widget::on_comboBox_currentTextChanged(const QString &arg1)
{
    qDebug() << ui->comboBox->currentText();
    QStringList list = resultMap[ui->comboBox->currentText()];
    // ui->plainTextEdit->clear();
    ui->plainTextEdit->appendPlainText(ui->comboBox->currentText());
    for (int i = 0; i < list.size(); ++i) {
        ui->plainTextEdit->appendPlainText(list.at(i));
    }
}


void Widget::on_pushButtonAdd_clicked()
{
    // 末尾插入一个项
    m_qStrListModel->insertRow(m_qStrListModel->rowCount());
    // 拿到项的 索引，最后一行，第 0 列的索引
    QModelIndex index = m_qStrListModel->index(m_qStrListModel->rowCount() - 1, 0);
    // model 设置数据 和角色
    m_qStrListModel->setData(index, QString("new item %1 ").arg(m_qStrListModel->rowCount()), Qt::DisplayRole);
    // 当前选中了
    ui->listView->setCurrentIndex(index);
}


void Widget::on_pushButtonDel_clicked()
{
    QModelIndex index = ui->listView->currentIndex();          //当前项的模型索引
    m_qStrListModel->removeRow(index.row());
}

